<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">

<head>
    <meta charset="UTF-8">
    <title>Flink任务管理</title>
    <link rel="stylesheet" href="/css/bootstrap.min.css">
    <link rel="stylesheet" href="/css/bootstrap-table.min.css">
    <link rel="stylesheet" href="/css/pub.css">
    <link rel="stylesheet" href="/css/jquery-confirm.min.css">
    <style>
        .container {
            margin: 20px auto;
            padding: 4px;
            width: 100% !important;
            max-width: 100% !important;
        }

        .split-layout {
            display: flex;
            flex-direction: column;
            gap: 20px;
            margin-top: 20px;
        }

        .panel {
            flex: 1;
            padding: 20px;
            border: 1px solid #ddd;
            border-radius: 5px;
            background: #fff;
        }

        .panel-title {
            margin-bottom: 20px;
            padding-bottom: 10px;
            border-bottom: 1px solid #eee;
        }

        .job-list {
            margin-top: 15px;
        }

        .status-running {
            color: #28a745;
        }

        .status-stopped {
            color: #dc3545;
        }

        .form-group {
            margin-bottom: 15px;
            display: flex;
            height: 40px;
        }

        .form-group label {
            width: 140px;
            line-height: 40px;
        }

        .form-group .form-input {
            flex: 1;
        }

        .form-group button {
            width: 100px;
            margin-left: 10px;
        }
    </style>
</head>

<body>
    <!-- 移除Bootstrap模态框和Toast容器 -->

    <div class="container">
        <div class="split-layout">
            <!-- 左侧：Flink服务连接表单 -->
            <div class="panel">
                <div class="form-group">
                    <label>Flink REST地址</label>
                    <div class="form-input">
                        <input type="text" class="form-control" id="url" placeholder="请输入Flink服务器地址，空则使用服务端设置">
                    </div>
                    <button class="btn btn-primary" id="btnQueryJob" onclick="onClickQueryJobList()">查询</button>
                </div>
            </div>

            <!-- 右侧：运行中的作业列表 -->
            <div class="panel">
                <h3 class="panel-title">运行中的作业</h3>
                <div class="job-list">
                    <table id="jobTable" data-ajax="ajaxQueryJobListPage" data-toggle="table" data-pagination="true"
                        data-side-pagination="client" data-page-size="10" data-page-list="[10, 25, 50, 100]"
                        data-search="false">
                        <thead>
                            <tr>
                                <th data-field="jid">作业ID</th>
                                <th data-field="name">作业名称</th>
                                <th data-field="state" data-formatter="stateFormatter">状态</th>
                                <th data-field="start-time" data-formatter="startTimeFormatter">开始时间</th>
                                <th data-field="end-time" data-formatter="endTimeFormatter">结束时间</th>
                                <th data-field="duration" data-formatter="durationFormatter">运行时长</th>
                                <th data-formatter="operateFormatter">操作</th>
                            </tr>
                        </thead>
                    </table>
                </div>
            </div>
        </div>
    </div>
</body>
<script src="/js/jquery-3.7.1.js"></script>
<script src="/js/bootstrap.bundle.min.js"></script>
<script src="/js/bootstrap-table.min.js"></script>
<script src="/js/jquery-confirm.min.js"></script>
<script src="/js/pub.js"></script>
<script>
    function ajaxQueryJobListPage(params) {
        $.ajax({
            url: "/flink/job/getJobs?url=" + $("#url").val(),
            type: "GET",
            headers: {
                "auth2045": getLoginToken()
            },
            contentType: "application/json",
            async: true,
            success: function (rs, status, xhr) {
                let r = JSON.parse(rs.data);
                params.success({ //注意，必须返回参数 params
                    "total": r.jobs.length,
                    "rows": r.jobs
                },
                    "ok", //这个好像暂时没有用到
                    xhr
                );
            },
            error: function (jqXHR, textStatus, errorThrown) {
                $.alert({
                    title: '警告',
                    content: "查询失败，网络错误:" + textStatus,
                    type: 'red',
                    buttons: {
                        ok: {
                            text: '确定',
                            btnClass: 'btn-primary'
                        }
                    }
                });
                params.success({ //注意，必须返回参数 params
                    "total": 0,
                    "rows": []
                },
                    "ok", //这个好像暂时没有用到
                    jqXHR
                );
            }
        });
    }

    function onClickQueryJobList() {
        $('#jobTable').bootstrapTable('refresh');
    }

    function operateFormatter(value, row) {
        if (row.state == "RUNNING") {
            return [
                '<button class="btn btn-sm btn-danger" onclick="cancelJob(\'' + row.jid + '\')">取消</button>'
            ].join(' ');
        }
        else {
            return [
                '<button class="btn btn-sm btn-secondary" disabled>取消</button>'
            ].join(' ');
        }
    }

    // 状态格式化
    function stateFormatter(value, row) {
        return value === 'RUNNING'
            ? '<span class="status-running">运行中</span>'
            : '<span class="status-stopped">已停止</span>';
    }

    function startTimeFormatter(value, row) {
        //把毫秒格式化为yyyy-mm-dd  hh24:mm:ss格式
        return new Date(value).toLocaleString();
    }

    function endTimeFormatter(value, row) {
        if (value == -1) {
            return "/";
        }
        else {
            return new Date(value).toLocaleString();
        }
    }

    // 时长格式化
    function durationFormatter(value) {
        if (value < 0) return '-';
        const hours = Math.floor(value / 3600000);
        const minutes = Math.floor((value % 3600000) / 60000);
        return `${hours}小时${minutes}分钟`;
    }


    function cancelJob(jobId) {
        $.confirm({
            title: '确认取消作业',
            content: '确定要取消这个作业吗？此操作不可撤销！',
            type: 'orange',
            buttons: {
                confirm: {
                    text: '确定取消',
                    btnClass: 'btn-danger',
                    action: function () {
                        $.ajax({
                            url: "/flink/job/cancelJob/" + jobId + "?url=" + $("#url").val(),
                            type: "GET",
                            headers: {
                                "auth2045": getLoginToken()
                            },
                            contentType: "application/json",
                            async: true,
                            beforeSend: function () {
                                // 显示加载状态
                                $('#btnQueryJob').prop('disabled', true).html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> 处理中...');
                            },
                            complete: function () {
                                // 恢复按钮状态
                                $('#btnQueryJob').prop('disabled', false).text('查询');
                            },
                            success: function (rs, status, xhr) {
                                console.log(rs);
                                if (rs.data) {
                                    showAlert('操作成功', '作业已成功取消', 'success');
                                    $('#jobTable').bootstrapTable('refresh');
                                }
                                else {
                                    showAlert('操作失败', rs.message || '取消作业失败', 'error');
                                }
                            },
                            error: function (jqXHR, textStatus, errorThrown) {
                                showAlert('网络错误', '取消失败: ' + textStatus, 'error');
                            }
                        });
                    }
                },
                cancel: {
                    text: '取消',
                    btnClass: 'btn-secondary'
                }
            }
        });
    }

    // 使用jquery-confirm显示提示
    function showAlert(title, message, type) {
        $.alert({
            title: title,
            content: message,
            type: type === 'success' ? 'green' : 'red',
            backgroundDismiss: true,
            animation: 'opacity',
            closeAnimation: 'opacity',
            animateFromElement: false,
            boxWidth: '400px',
            useBootstrap: false,
            buttons: {
                ok: {
                    text: '确定',
                    btnClass: type === 'success' ? 'btn-success' : 'btn-danger',
                    action: function () {
                    }
                }
            }
        });
    }
</script>